
;(function(window){

	var Vertex = function(label){
		return {
			label: label
		};
	};


	var GraphD = function(){
		this._MAX_VERTS = 20;
		this._vertexList = []; // 存储顶点的数组
		this._adjMat = []; // 邻接矩阵（二维数组）
		this._vtxLn = 0;
		this._sortedArray = [];

		for( var i=0;i<this._MAX_VERTS;i++){
			this._adjMat[i] = [];
			for( var j=0;j<this._MAX_VERTS;j++)
				this._adjMat[i][j] = 0;
		}
	};
	GraphD.prototype={
		constructor: GraphD,
		addVertex: function(label){
			this._vertexList[this._vtxLn] = Vertex(label);
			this._vtxLn = this._vtxLn + 1;
		},
		addEdge: function(start, end){
			this._adjMat[start][end] = 1;
		},
		_noSuccessor: function(){
			var isEdge;
			for(var row=0; row<this._vtxLn; row=row+1){
				isEdge = false;
				for( var col=0; col<this._vtxLn; col=col+1){
					if( this._adjMat[row][col]>0){
						isEdge = true;
						break;
					}
				}
				if( !isEdge ) return row;
			}
			return -1;
		},
		_moveRowUp: function(row, length){
			for(var col=0;col<length;col=col+1)
				this._adjMat[row][col] = this._adjMat[row+1][col];
		},
		_moveColLeft: function(col, length){
			for(var row=0;row<length;row=row+1)
				this._adjMat[row][col] = this._adjMat[row][col+1];
		},
		_deleteVertex: function(delVert){
			if( delVert!=this._vtxLn-1){
				for(var j=delVert; j<this._vtxLn-1;j=j+1)
					this._vertexList[j] = this._vertexList[j+1];
				for(var row=delVert; row<this._vtxLn-1;row=row+1)
					this._moveRowUp(row, this._vtxLn);
				for(var col=delVert; col<this._vtxLn-1;col=col+1)
					this._moveColLeft(col, this._vtxLn-1);
			}
			this._vtxLn = this._vtxLn-1;
		},
		topo: function(){
			//var origVtxLn = this._vtxLn;
			while(this._vtxLn>0){
				var currentVtx = this._noSuccessor();
				if( currentVtx == -1){
					throw new Error('图存在环');
				}
				this._sortedArray[this._vtxLn-1] = this._vertexList[currentVtx].label;
				this._deleteVertex(currentVtx);
			}
			// 删除了所有顶点
			return this._sortedArray;
		}

	};

	window.GraphD = GraphD;
})(window);